package com.ysd.lis.service.inti.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ysd.common.Result;
import com.ysd.lis.entity.bac.BacBloodCultrue;
import com.ysd.lis.entity.bac.BacCultureMedium;
import com.ysd.lis.entity.bac.BacTestCultureMedium;
import com.ysd.lis.entity.inti.IntInstrBloodResult;
import com.ysd.lis.entity.inti.IntInstrBloodResultLog;
import com.ysd.lis.entity.lab.LabMaininfo;
import com.ysd.lis.mapper.bac.BacTestCultureMediumMapper;
import com.ysd.lis.mapper.inti.IntInstrBloodResultMapper;
import com.ysd.lis.mapper.lab.LabMaininfoMapper;
import com.ysd.lis.service.bac.BacBloodCultrueService;
import com.ysd.lis.service.inti.IntInstrBloodResultLogService;
import com.ysd.lis.service.inti.IntInstrBloodResultService;
import com.ysd.lis.socket.MessageTemplate;
import com.ysd.lis.socket.WebSocketUtils;
import com.ysd.util.ToolsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author prs
 * @since 2025-03-28
 */
@Service
public class IntInstrBloodResultServiceImpl extends ServiceImpl<IntInstrBloodResultMapper, IntInstrBloodResult> implements IntInstrBloodResultService {

    @Autowired
    IntInstrBloodResultMapper intInstrBloodResultMapper;
    @Autowired
    LabMaininfoMapper labMaininfoMapper;
    @Autowired
    BacTestCultureMediumMapper bacTestCultureMediumMapper;
    @Autowired
    BacBloodCultrueService bacBloodCultrueService;

    @Autowired
    IntInstrBloodResultLogService intInstrBloodResultLogService;
    @Override
    public Result transIntInstrBloodResult() {
        //从结果表中按照最新的时间查出500条数据
        Page<IntInstrBloodResult> page = new Page<>();
        page.setCurrent(1);
        page.setSize(500);
        Calendar calendar = Calendar.getInstance(); // 获取当前日期的Calendar实例
        Date today = calendar.getTime();
        //取500条数据
        LambdaQueryWrapper<IntInstrBloodResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .and(p -> p.eq(IntInstrBloodResult::getIsNoChannel, "N").or().isNull(IntInstrBloodResult::getIsNoChannel))
                .ge(IntInstrBloodResult::getCreateTime, DateUtil.beginOfDay(today).toTimestamp())
                .le(IntInstrBloodResult::getCreateTime, DateUtil.endOfDay(today).toTimestamp())
                .orderByAsc(IntInstrBloodResult::getCreateTime);
        Page<IntInstrBloodResult> intInstrBloodResultPage = intInstrBloodResultMapper.selectPage(page, queryWrapper);
        List<IntInstrBloodResult> intInstrBloodResults = intInstrBloodResultPage.getRecords();
        if (ToolsUtils.isNotEmpty(intInstrBloodResults)) {
            List<IntInstrBloodResult> delInstrBloodResultList = new ArrayList<>();
            //循环仪器接口结果
            for (IntInstrBloodResult intInstrBloodResult : intInstrBloodResults) {
                String sampleNo = intInstrBloodResult.getSampleNo();
                String rptGroup = intInstrBloodResult.getRptGroup();
                Timestamp sampleda = intInstrBloodResult.getSampleda();
                String resultOrgId = intInstrBloodResult.getOrgId();
                if (ToolsUtils.isNotEmpty(sampleda) && ToolsUtils.isNotEmpty(rptGroup)
                        && ToolsUtils.isNotEmpty(sampleNo) && ToolsUtils.isNotEmpty(resultOrgId)) {
                    //按照分组后的数据生成labMaininfo数据
                    LabMaininfo labMaininfo = null;

                    //优先按条码号查询
                    LambdaQueryWrapper<LabMaininfo> queryWrapper2 = new LambdaQueryWrapper<>();
                    queryWrapper2.eq(LabMaininfo::getDelFlag, 0)
                            .eq(LabMaininfo::getRptGroup, rptGroup)
                            .eq(LabMaininfo::getReqNo, sampleNo)
                            .eq(LabMaininfo::getOrgId, resultOrgId);
                    List<LabMaininfo> maininfoList = labMaininfoMapper.selectList(queryWrapper2);
                    if (ToolsUtils.isNotEmpty(maininfoList)) {
                        labMaininfo = maininfoList.get(0);
                    } else {
                        //标本号查询
                        LambdaQueryWrapper<LabMaininfo> queryWrapper3 = new LambdaQueryWrapper<>();
                        queryWrapper3.eq(LabMaininfo::getDelFlag, 0)
                                .eq(LabMaininfo::getRptGroup, rptGroup)
                                .eq(LabMaininfo::getSampleNo, sampleNo)
                                .eq(LabMaininfo::getOrgId, resultOrgId);
                        List<LabMaininfo> maininfoList1 = labMaininfoMapper.selectList(queryWrapper3);
                        if (ToolsUtils.isNotEmpty(maininfoList1)) {
                            labMaininfo = maininfoList1.get(0);
                        }
                    }
                    if(ToolsUtils.isNotEmpty(labMaininfo)){
                        BigDecimal isChk = labMaininfo.getIsChk();
                        if (ToolsUtils.isNotEmpty(isChk) && isChk.intValue() > 0) {
                            delInstrBloodResultList.add(intInstrBloodResult);
                            continue;
                        }
                        //处理结果列表=======
                        //获取血瓶编码
                        String format = DateUtil.format(labMaininfo.getSampleda(), "yyyy-MM-dd");
                        Timestamp startTime = Timestamp.valueOf(format + " 00:00:00");
                        Timestamp endTime = Timestamp.valueOf(format + " 23:59:59");
                        String mainSampleNo = labMaininfo.getSampleNo();
                        //1 先获取此标本得培养瓶数据
                        MPJLambdaWrapper<BacTestCultureMedium> queryMediumWrapper = new MPJLambdaWrapper<>();
                        queryMediumWrapper.selectAll(BacTestCultureMedium.class)
                                .innerJoin(BacCultureMedium.class, "tb1",
                                        p -> p.eq(BacCultureMedium::getCode, BacTestCultureMedium::getCultureNo)
                                                .eq(BacCultureMedium::getBloodFlag, 1)
                                                .eq(BacCultureMedium::getMediumType, "2")
                                                .eq(BacCultureMedium::getOrgId, resultOrgId)
                                                .eq(BacCultureMedium::getDelFlag, 0))
                                .eq(BacTestCultureMedium::getRptGroup, rptGroup)
                                .eq(BacTestCultureMedium::getSampleNo, mainSampleNo)
                                .ge(BacTestCultureMedium::getSampleda, startTime)
                                .le(BacTestCultureMedium::getSampleda, endTime)
                                .eq(BacTestCultureMedium::getDelFlag, 0)
                                .eq(BacTestCultureMedium::getOrgId, resultOrgId);
                                //.eq(StrUtil.isNotEmpty(barcode), BacTestCultureMedium::getBarcode, barcode);
                        List<BacTestCultureMedium> bacTestCultureMediumList = bacTestCultureMediumMapper.selectList(queryMediumWrapper);
                        if(ToolsUtils.isNotEmpty(bacTestCultureMediumList)){
                            BacTestCultureMedium bacTestCultureMedium = null;
                            //先查询是否存在barcode有的数据有则用这个 没有则取第一条 并且回写此barcode
                            String barcode = intInstrBloodResult.getBarcode();

                            if(ToolsUtils.isNotEmpty(barcode)){
                                List<BacTestCultureMedium> collect = bacTestCultureMediumList.stream().filter(a -> barcode.equals(a.getBarcode())).collect(Collectors.toList());
                                if(ToolsUtils.isNotEmpty(collect)){
                                    bacTestCultureMedium = collect.get(0);
                                }else {
                                    bacTestCultureMedium = bacTestCultureMediumList.get(0);
                                    bacTestCultureMedium.setBarcode(barcode);
                                    bacTestCultureMediumMapper.updateById(bacTestCultureMedium);
                                }
                            }else {
                                bacTestCultureMedium = bacTestCultureMediumList.get(0);
                            }

                            BacBloodCultrue bloodCultrue = new BacBloodCultrue();
                            bloodCultrue.setRptGroup(rptGroup);
                            bloodCultrue.setSampleda(startTime);
                            bloodCultrue.setSampleNo(mainSampleNo);
                            bloodCultrue.setTestFlowNo(bacTestCultureMedium.getTestFlowNo());
                            bloodCultrue.setTestNodeNo("YQPY");
                            bloodCultrue.setReqNo(labMaininfo.getReqNo());
                            bloodCultrue.setBarcode(barcode);
                            bloodCultrue.setCulMediumNo(bacTestCultureMedium.getCultureNo());
                            bloodCultrue.setCulMediumNa(bacTestCultureMedium.getCultureNa());
                            bloodCultrue.setBottleNo(barcode);
                            bloodCultrue.setTestTime(intInstrBloodResult.getTestTime());
                            bloodCultrue.setResultTime(intInstrBloodResult.getResultTime());
                            bloodCultrue.setPosInfo(intInstrBloodResult.getPosInfo());
                            String resultType = intInstrBloodResult.getResultType();
                            if (ToolsUtils.isNotEmpty(resultType)) {
                                if (resultType.equals("1")) {
                                    bloodCultrue.setIsPositive(1);
                                    bloodCultrue.setIsAlarm((double) 1);
                                    bloodCultrue.setResult("阳性");
                                    bloodCultrue.setAlarmText("阳性结果");
                                } else {
                                    bloodCultrue.setIsPositive(0);
                                    bloodCultrue.setIsAlarm((double) 0);
                                    bloodCultrue.setResult("阴性");
                                    bloodCultrue.setAlarmText("");
                                }
                            }
                            bloodCultrue.setOrgId(labMaininfo.getOrgId());
                            // 计算时间差
                            long timeDifference = bloodCultrue.getResultTime().getTime() - bloodCultrue.getTestTime().getTime();
                            long diffDays = timeDifference / (24 * 60 * 60 * 1000);
                            long diffHours = (timeDifference % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000);
                            long diffMinutes = (timeDifference % (60 * 60 * 1000)) / (60 * 1000);
                            bloodCultrue.setExpoTime(diffDays + "天" + diffHours + "时" + diffMinutes + "分");

                            LambdaQueryWrapper<BacBloodCultrue> lambdaQueryWrappers = new LambdaQueryWrapper<>();
                            lambdaQueryWrappers
                                    .eq(BacBloodCultrue::getSampleNo, mainSampleNo)
                                    .eq(BacBloodCultrue::getRptGroup, rptGroup)
                                    .eq(BacBloodCultrue::getCulMediumNo,bacTestCultureMedium.getCultureNo())
                                    .ge(BacBloodCultrue::getSampleda, startTime)
                                    .le(BacBloodCultrue::getSampleda, endTime)
                                    .eq(BacBloodCultrue::getOrgId, labMaininfo.getOrgId())
                                    .eq(BacBloodCultrue::getDelFlag, 0);

                            boolean b = bacBloodCultrueService.saveOrUpdate(bloodCultrue, lambdaQueryWrappers);
                            if(b){
                                //跟新上机记录得危急值状态
                                LambdaUpdateWrapper<LabMaininfo> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                                lambdaUpdateWrapper
                                        .eq(LabMaininfo::getRptGroup, rptGroup)
                                        .eq(LabMaininfo::getSampleNo,mainSampleNo)
                                        .ge(LabMaininfo::getSampleda, startTime)
                                        .le(LabMaininfo::getSampleda, endTime)
                                        .eq(LabMaininfo::getOrgId,resultOrgId);
                                if(bloodCultrue.getIsAlarm() == 1){
                                    lambdaUpdateWrapper.set(LabMaininfo::getIsAlarm, 1);
                                }else {
                                    lambdaUpdateWrapper.set(LabMaininfo::getIsAlarm, 0);
                                }
                                int update = labMaininfoMapper.update(null, lambdaUpdateWrapper);

                                //推送前端刷新结果
                                MessageTemplate messageTemplate = new MessageTemplate();
                                messageTemplate.setLabMaininfo(labMaininfo);
                                messageTemplate.setType("RefreshBloodResults");
                                WebSocketUtils.sendAllMessage(messageTemplate);

                                delInstrBloodResultList.add(intInstrBloodResult);
                            }
                        }
                    }
                }
            }//循环结束

            if (ToolsUtils.isNotEmpty(delInstrBloodResultList)) {
                //删除
                List<String> ids = delInstrBloodResultList.stream().map(IntInstrBloodResult::getId).collect(Collectors.toList());
                this.removeByIds(ids);
                //插入log
                List<IntInstrBloodResultLog> addLogList = new ArrayList<>();
                for (IntInstrBloodResult iResult : delInstrBloodResultList) {
                    IntInstrBloodResultLog resultLog = new IntInstrBloodResultLog();
                    BeanUtil.copyProperties(iResult, resultLog, "id");
                    resultLog.setInstrBloodResultId(iResult.getId());
                    addLogList.add(resultLog);
                }
                intInstrBloodResultLogService.saveBatch(addLogList);
            }

        }

        new Thread(() -> {
            this.removeIntInstrBloodResults();
        }).start();
        return Result.succ(1, "同步结果成功", null);
    }

    private void removeIntInstrBloodResults() {
        //删除创建时间30天之前的数据
        LambdaQueryWrapper<IntInstrBloodResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.le(IntInstrBloodResult::getCreateTime, DateUtil.offsetDay(new Date(), -30));
        this.remove(queryWrapper);
        //删除INT_INSTR_BLOOD_RESULT_LOG表中30天之前的数据
        LambdaQueryWrapper<IntInstrBloodResultLog> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.le(IntInstrBloodResultLog::getCreateTime, DateUtil.offsetDay(new Date(), -30));
        intInstrBloodResultLogService.remove(queryWrapper1);
    }
}
